﻿using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Core
{
    public class WebControlUtil
    {
        /// <summary>
        /// Gets the drop down index by value.
        /// </summary>
        /// <param name="ddl">The DDL.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static int GetDropDownIndexByValue(DropDownList ddl, object value)
        {
            int index = -1;

            if (value != null)
            {
                index = ddl.Items.IndexOf(ddl.Items.FindByValue(value.ToString()));
            }

            return index;
        }

        /// <summary>
        /// Gets the drop down index by text.
        /// </summary>
        /// <param name="ddl">The DDL.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static int GetDropDownIndexByText(DropDownList ddl, object value)
        {
            int index = -1;

            if (value != null)
            {
                index = ddl.Items.IndexOf(ddl.Items.FindByText(value.ToString()));
            }

            return index;
        }

        /// <summary>
        /// Sets the drop down index by value.
        /// </summary>
        /// <param name="ddl">The DDL.</param>
        /// <param name="value">The value.</param>
        public static void SetDropDownIndexByValue(DropDownList ddl, object value)
        {
            ddl.SelectedIndex = GetDropDownIndexByValue(ddl, value);
        }

        /// <summary>
        /// Sets the text box to lower case.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void SetTextBoxToLowerCase(TextBox txtBox)
        {
            if (txtBox != null)
            {
                txtBox.Style["text-transform"] = "lowercase";
            }
        }

        /// <summary>
        /// Sets the text box to upper case.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void SetTextBoxToUpperCase(TextBox txtBox)
        {
            if (txtBox != null)
            {
                txtBox.Style["text-transform"] = "uppercase";
            }
        }

        /// <summary>
        /// Sets the read only.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void SetReadOnly(TextBox txtBox)
        {
            if (txtBox != null)
            {
                txtBox.BackColor = System.Drawing.Color.Gainsboro;
                txtBox.Attributes.Add("readonly", "true");
            }
        }

        /// <summary>
        /// Sets the default button.
        /// </summary>
        /// <param name="btn">The BTN.</param>
        public static void SetDefaultButton(Button btn)
        {
            Page pg = (HttpContext.Current.Handler as Page);
            ScriptManager sm = ScriptManager.GetCurrent(pg);
            if (sm != null)
            {
                sm.SetFocus(btn);
                if (pg != null) pg.Form.DefaultButton = btn.UniqueID;
            }
        }

        /// <summary>
        /// Sets the focus.
        /// </summary>
        /// <param name="ctl">The CTL.</param>
        public static void SetFocus(Control ctl)
        {
            Page pg = (HttpContext.Current.Handler as Page);

            ScriptManager sm = ScriptManager.GetCurrent(pg);
            if (sm != null)
            {
                sm.SetFocus(ctl);
            }
            else
            {
                ctl.Focus();
            }
        }

        /// <summary>
        /// Sets the focus.
        /// </summary>
        /// <param name="pg">The pg.</param>
        /// <param name="ctl">The CTL.</param>
        public static void SetFocus(Page pg, Control ctl)
        {
            ScriptManager sm = ScriptManager.GetCurrent(pg);
            if (sm != null)
            {
                sm.SetFocus(ctl);
            }
        }

        /// <summary>
        /// Sets the focus in grid view.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="controlID">The control ID.</param>
        /// <param name="gv">The gv.</param>
        public static void SetFocusInGridView(int index, string controlID, GridView gv)
        {
            GridViewRow row = gv.Rows[index];

            //... find the first control in the row to be edited ...
            WebControl controlToGetFocus = (WebControl)row.FindControl(controlID);

            //... and set the focus on that control. 

            ScriptManager sm = ScriptManager.GetCurrent(gv.Page);
            if (sm != null)
            {
                sm.SetFocus(controlToGetFocus);
            }

            //Highlight text (if any) in the control 
            //controlToGetFocus.Attributes["onfocus"] = "javascript:" + controlToGetFocus.ClientID + ".select();";
        }

        /// <summary>
        /// Sets the focus in grid view.
        /// </summary>
        /// <param name="rowIndex">Index of the row.</param>
        /// <param name="colIndex">Index of the col.</param>
        /// <param name="gv">The gv.</param>
        public static void SetFocusInGridView(int rowIndex, int colIndex, GridView gv)
        {
            GridViewRow row = gv.Rows[rowIndex];

            //... find the first control in the row to be edited ...
            WebControl controlToGetFocus = (WebControl)row.Cells[colIndex].Controls[0];

            //... and set the focus on that control. 
            ScriptManager sm = ScriptManager.GetCurrent(gv.Page);
            if (sm != null)
            {
                sm.SetFocus(controlToGetFocus);
            }

            //Highlight text (if any) in the control 
            //controlToGetFocus.Attributes["onfocus"] = "javascript:" + controlToGetFocus.ClientID + ".select();";
        }

        /// <summary>
        /// Gets the post back control.
        /// </summary>
        /// <returns></returns>
        public static Control GetPostBackControl()
        {
            Page page = (HttpContext.Current.Handler as Page);

            if (page != null)
            {
                ScriptManager sm = ScriptManager.GetCurrent(page);
                if (sm != null)
                {
                    string ctrlname = sm.AsyncPostBackSourceElementID;
                    Control control = page.FindControl(ctrlname);
                    return control;
                }
            }
            return null;
        }

        /// <summary>
        /// Sets the calendar control.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void SetCalendarControl(TextBox txtBox)
        {
            txtBox.Attributes.Add("readonly", "true");
            txtBox.Attributes.Add("onclick", "return showCalendar('" + txtBox.ClientID + "','%d/%m/%Y');");
        }

        /// <summary>
        /// Sets the calendar control.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        /// <param name="imgBtn">The img BTN.</param>
        public static void SetCalendarControl(TextBox txtBox, ImageButton imgBtn)
        {
            txtBox.Attributes.Add("readonly", "true");
            imgBtn.Attributes.Add("onclick", "return showCalendar('" + txtBox.ClientID + "','%d/%m/%Y');");
        }

        /// <summary>
        /// Disables the copy and paste.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void DisableCopyAndPaste(TextBox txtBox)
        {
            txtBox.Attributes.Add("onCopy", "return false");
            txtBox.Attributes.Add("onCut", "return false");
            txtBox.Attributes.Add("onPaste", "return false");
        }

        /// <summary>
        /// Disables the paste.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void DisablePaste(TextBox txtBox)
        {
            txtBox.Attributes.Add("onPaste", "return false");
        }

        /// <summary>
        /// Disables the auto complete.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void DisableAutoComplete(TextBox txtBox)
        {
            txtBox.Attributes.Add("autocomplete", "off");
        }

        /// <summary>
        /// Sets the time control.
        /// </summary>
        /// <param name="txtBox">The TXT box.</param>
        public static void SetTimeControl(TextBox txtBox)
        {
            txtBox.Style["text-align"] = "center";
            txtBox.Attributes.Add("onchange", "checkTime('" + txtBox.ClientID + "')");
        }

        /// <summary>
        /// Sets the disable button after click.
        /// </summary>
        /// <param name="btn">The BTN.</param>
        public static void SetDisableButtonAfterClick(Button btn)
        {
            Page page = (HttpContext.Current.Handler as Page);
            if (page != null)
                btn.Attributes.Add("onclick", "this.disabled=true;" + page.ClientScript.GetPostBackEventReference(btn, null));
        }

        #region "Get Value from Textbox"

        /// <summary>
        /// Gets the value from text box.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="txtBox">The TXT box.</param>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public static T? GetValueFromTextBox<T>(TextBox txtBox, T? obj) where T : struct
        {
            if (string.IsNullOrEmpty(txtBox.Text))
            {
                if (GenericUtil.IsNullable(obj))
                {
                    return null;
                }
                {
                    var changeType = Convert.ChangeType("", typeof(T));
                    if (changeType != null)
                        return (T)changeType;
                }
            }
            {
                var changeType = Convert.ChangeType(txtBox.Text, typeof(T));
                if (changeType != null)
                    return (T)changeType;
            }

            return default(T);
        }

        /// <summary>
        /// Gets the value from text box.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="txtBox">The TXT box.</param>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public static T GetValueFromTextBox<T>(TextBox txtBox, T obj) where T : struct
        {
            if (string.IsNullOrEmpty(txtBox.Text))
            {
                if (obj is DateTime)
                {
                    var changeType = Convert.ChangeType(DateTime.MinValue, typeof(T));
                    if (changeType != null)
                        return (T)changeType;
                }
                if (obj is decimal || obj is Int32 || obj is double)
                {
                    var changeType = Convert.ChangeType("0", typeof(T));
                    if (changeType != null)
                        return (T)changeType;
                }
                var type = Convert.ChangeType("", typeof(T));
                if (type != null)
                    return (T)type;
            }
            if (obj is DateTime)
            {
                var changeType = Convert.ChangeType(DateTimeUtil.GetDateTimeFromString(txtBox.Text), typeof(T));
                if (changeType != null)
                    return (T)changeType;
            }
            var o = Convert.ChangeType(txtBox.Text, typeof(T));
            if (o != null)
                return (T)o;

            return default(T);
        }

        #endregion

        #region "FindControl Recursive in Control"

        /// <summary>
        /// Finds the control recursive.
        /// </summary>
        /// <param name="root">The root.</param>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public static Control FindControlRecursive(Control root, string id)
        {
            if (root.ID == id)
            {
                return root;
            }

            foreach (Control ctl in root.Controls)
            {
                Control foundCtl = FindControlRecursive(ctl, id);
                if (foundCtl != null)
                {
                    return foundCtl;
                }
            }

            return null;
        }

        /// <summary>
        /// Finds the button recursive.
        /// </summary>
        /// <param name="root">The root.</param>
        /// <returns></returns>
        public static Control FindButtonRecursive(Control root)
        {
            if (root is Button)
            {
                return root;
            }

            foreach (Control ctl in root.Controls)
            {
                Control foundCtl = FindButtonRecursive(ctl);
                if (foundCtl != null)
                {
                    return foundCtl;
                }
            }

            return null;
        }

        /// <summary>
        /// Finds the control recursive with generics.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="root">The root.</param>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public static T FindControlRecursiveWithGenerics<T>(Control root, string id) where T : Control
        {
            if (root.ID == id)
            {
                return root as T;
            }

            foreach (Control ctl in root.Controls)
            {
                Control foundCtl = FindControlRecursive(ctl, id);
                if (foundCtl != null)
                {
                    return foundCtl as T;
                }
            }

            return null;
        }

        /// <summary>
        /// This use for setting the max length for textbox control in case of single line and multiple line.
        /// Remark: Should be declare this function in Page_Init or Page_Load event
        /// </summary>
        /// <param name="textBox">The text box.</param>
        /// <param name="maxLen">The max len.</param>
        public static void SetMaxLength(TextBox textBox, int maxLen)
        {
            string script = "if(" + textBox.UniqueID + ".value.length>" + maxLen + ") {" + textBox.UniqueID +
                            ".value=" + textBox.UniqueID + ".value.substring(0," + maxLen + ");} ";
            if (textBox.TextMode == TextBoxMode.MultiLine)
            {
                textBox.Attributes.Add("onkeyup", script);
                textBox.Attributes.Add("onBlur", script);
                textBox.Attributes.Add("onChange", script);
            }
            else
            {
                textBox.MaxLength = maxLen;
            }
        }

        #endregion
    }
}
